// Boost.Range library
//
//  Copyright Fernando Pelliccioni 2011. Use, modification and
//  distribution is subject to the Boost Software License, Version
//  1.0. (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//
// For more information, see http://www.boost.org/libs/range/
//

#ifndef BOOST_RANGE_ADAPTOR_BASE64_HPP
#define BOOST_RANGE_ADAPTOR_BASE64_HPP

#include <boost/range/adaptor/argument_fwd.hpp>
#include <boost/range/size_type.hpp>
#include <boost/range/iterator_range.hpp>

namespace boost
{

    namespace range_detail
    {
        template <typename R>
        class base64_range 
			: public boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<R>::type >
        {
            typedef boost::iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<R>::type > base_t;
        public:
			typedef BOOST_DEDUCED_TYPENAME boost::range_iterator<R>::type iterator;

            //template <typename Rng, typename T, typename U>
            //base64_range(Rng& rng, T t, U u)
            //    : base_t(boost::make_iterator_range(rng, t, u - boost::size(rng)))
            //{
            //}

			template <typename Rng>
            base64_range( Rng& rng )
                : base_t( boost::make_iterator_range(rng) )
            {}
        };

		struct base64_forwarder {};


		template <typename R>
		inline base64_range<R>
		operator|( R& r, base64_forwarder )
		{
			return base64_range<R>( r );
		}

		template <typename R>
		inline base64_range<const R>
		operator|( const R& r, base64_forwarder )
		{
			return base64_range<const R>( r );
		}
	} //namespace range_detail

	using range_detail::base64_range;

    namespace adaptors
    {
        namespace
        {
            const range_detail::base64_forwarder base64ed = range_detail::base64_forwarder();
        }

        template <typename R>
        inline base64_range<R>
        base64convert( R & rng)
        {
            return base64_range<R>(rng);
        }
        
        template <typename R>
        inline base64_range<const R>
        base64convert( R const& rng)
        {
            return base64_range<const R>(rng);
        }

        //struct sliced
        //{
        //    sliced(std::size_t t_, std::size_t u_)
        //        : t(t_), u(u_) {}
        //    std::size_t t;
        //    std::size_t u;
        //};

        //namespace
        //{
        //    const range_detail::reverse_forwarder reversed = 
        //                                    range_detail::reverse_forwarder();
        //}



        //template <typename R>
        //inline base64_range<R>
        //base64( R& rng, std::size_t t, std::size_t u )
        //{
        //    BOOST_ASSERT( t <= u && "error in slice indices" );
        //    BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
        //                  "second slice index out of bounds" );

        //    return base64_range<R>(rng);	//, t, u);
        //}

        //template <typename R>
        //inline iterator_range< BOOST_DEDUCED_TYPENAME range_iterator<const R>::type >
        //base64( const R& rng, std::size_t t, std::size_t u )
        //{
        //    BOOST_ASSERT( t <= u && "error in slice indices" );
        //    BOOST_ASSERT( static_cast<std::size_t>(boost::size(rng)) >= u &&
        //                  "second slice index out of bounds" );

        //    return base64_range<const R>(rng);	//, t, u);
        //}

        //template <typename R>
        //inline base64_range<R>
        //operator|( R& r, const sliced& f )
        //{
        //    return base64_range<R>( r);	//, f.t, f.u );
        //}

        //template <typename R>
        //inline base64_range<const R>
        //operator|( const R& r, const sliced& f )
        //{
        //    return base64_range<const R>( r);	//, f.t, f.u );
        //}


    } // namespace adaptors
    //using adaptors::base64_range;
} // namespace boost

#endif //BOOST_RANGE_ADAPTOR_BASE64_HPP
